//
//  File.swift
//  Nairacup
//
//  Created by wy on 2024/10/15.
//

import Foundation
import CoreTelephony
import UIKit
import Network
import KeychainAccess
import Photos
import NetworkExtension

class LoanIosDeviceBaseInfo {
    //唯一标识设备的UUID
    var deviceUuid: String?
    //设备的品牌，如 "Apple"
    var brand: String?
    //设备的型号，如 "iPhone XR"
    var model: String?
    //设备的名称，如 "iPhone"
    var deviceName: String?
    //操作系统的SDK版本号
    var sdkVersion: Int?
    //操作系统的版本号，如 "17.5.1"
    var release: String?
    //设备的电话类型，0 代表无电话功能
    var phoneType: Int?
    //CPU核心数
    var coresCpu: Int?
    //设备的物理尺寸，通常表示屏幕的对角线长度（单位：英寸）
    var physicalSize: CGFloat?
    //以下是扩展信息
    //扩展序列号
    var extSn: String?
    //设备高度（以像素为单位）
    var deviceHeight: CGFloat?
    //设备宽度（以像素为单位）
    var deviceWidth: CGFloat?
    //信号强度（以 dBm 为单位）
    var dbmClass: String?
    //设备总内存（以字节为单位）
    var totalMemory: String?
    //视频数量
    var video: Int?
    //当前内存（以字节为单位）
    var memory: String?
    //存储总量（以字节为单位）
    var storage: String?
    // 图片数量
    var picCount: Int?
    //IDFA 权限（0：未授权，1：已授权）
    var idfaPermissions: Int?
    //通知权限（0：未授权，1：已授权）
    var notificationPermissions: Int?
    //日历权限（0：未授权，1：已授权）
    var calendarPermissions: Int?
    //提醒权限（0：未授权，1：已授权）
    var reminderPermissions: Int?
    //手机 Wi-Fi 信号强度
    var phoneWifiSignalStrength: Int?
    //网络类型（如 3G、4G、5G 等）
    var networkType: String?
    //IP 地址
    var ip: String?
    //外部音频存储的大小（以字节为单位）
    var audioExternal: Int?
    //内部音频存储的大小（以字节为单位）
    var audioInternal: Int?
    //内部视频存储的大小（以字节为单位）
    var videoInternal: Int?
    //外部视频存储的大小（以字节为单位）
    var videoExternal: Int?
    //下载文件的大小（以字节为单位）
    var downloadFiles: Int?
    //设备是否已root或越狱，0表示未root或越狱，1表示已root或越狱
    var isRootJailbreak: Int?
    //设备是否可以拨打电话，1表示可以，0表示不可以
    var canCallPhone: Int?
    //当前使用的键盘类型
    var keyboardType: Int?
    //设备是否使用代理端口，0表示未使用，1表示使用
    var isUsingProxyPort: Int?
    //设备是否使用VPN，0表示未使用，1表示使用
    var isUsingVpn: Int?
    //设备是否启用USB调试模式，0表示未启用，1表示启用
    var isUsbDebug: Int?
    //设备的最后启动时间，时间戳格式 精确到毫秒
    var lastBootTime: Int?
    //设备是否使用模拟位置，0表示未使用，1表示使用
    var isMockLocation: Int?
    //设备是否为模拟器，0表示非模拟器，1表示模拟器
    var isSimulator: Int?
    //电池信息
    //设备是否正在充电（0：否，1：是）
    var isCharging: Int?
    //当前电池百分比（0-100）
    var batteryPct: Int?
    //语言
    //语言的 ISO 639-2 代码，例如 "aa"
    var localeIso3Language: String?
    //显示的语言，例如 "aa"
    var localeDisplayLanguage: String?
    // 国家代码的 ISO 3166-1 代码，例如 "AC"
    var localeIso3Country: String?
    //语言标识，通常是语言和国家代码的组合，例如 "en-TH"
    var language: String?
    //时区标识，例如 "Africa/Dar_es_Salaam"
    var timeZoneId: String?

    func getData() {
        deviceUuid = UniqueIdentifierManager.getUniqueIdentifier()
        brand = "Apple"
        model = UIDevice.current.phoneModel
        deviceName = UIDevice.current.name
        sdkVersion = ProcessInfo.processInfo.operatingSystemVersion.majorVersion
        release = ModelTools.getSDKVersion()
        phoneType = ModelTools.getPhoneCapability()
        coresCpu = ProcessInfo.processInfo.activeProcessorCount
        physicalSize = ModelTools.getDeviceDiagonalSizeInInches()
        extSn = ""
        deviceHeight = UIScreen.main.bounds.size.height
        deviceWidth = UIScreen.main.bounds.size.width
        dbmClass = "-1"
        totalMemory = "\(ProcessInfo.processInfo.physicalMemory)"
        ModelTools.getVideoCount(completion: { [weak self] count in
            self?.video = count
        })
        memory = "\(ModelTools.getMemoryUsage())"
        storage = "\(ModelTools.getTotalDiskSpaceInBytes())"
        ModelTools.getPhotoCount(completion: { [weak self] count in
            self?.picCount = count
        })
        idfaPermissions = Const.idfa.count > 0 ? 1 : 0
        notificationPermissions = 0
        AuthTools.checkCalendarPermission({ [weak self] status in
            self?.calendarPermissions = status == .authorized ? 1 : 0
            self?.reminderPermissions = status == .authorized ? 1 : 0
        })
        phoneWifiSignalStrength = -1
        ModelTools.getNetworkType { [weak self] type in
            self?.networkType = type
        }
        ModelTools.getAllAudioSize { [weak self] size in
            self?.audioExternal = size
            self?.audioInternal = size
        }
        ModelTools.getAllVideoSize { [weak self] size in
            self?.videoExternal = size
            self?.videoInternal = size
        }
        downloadFiles = 0
        isRootJailbreak = ModelTools.isDeviceJailbroken() ? 1 : 0
        canCallPhone = ModelTools.canMakePhoneCalls() ? 1 : 0
        keyboardType = -1
        isUsingProxyPort = ModelTools.checkProxy() ? 1 : 0
        ModelTools.checkVPNStatus{ [weak self] status in
            self?.isUsingVpn = status ? 1 : 0
        }
        isUsbDebug = 1
        lastBootTime = -1
        isMockLocation = 0
        isSimulator = ModelTools.isRunningOnSimulator() ? 1 : 0
        isCharging = ModelTools.isDeviceCharging() ? 1 : 0
        batteryPct = Int(ModelTools.getBatteryPercentage())
        localeIso3Language = Locale.current.languageCode
        localeDisplayLanguage = Locale.current.scriptCode
        localeIso3Country = Locale.current.regionCode
        language = "\(localeDisplayLanguage ?? "")-\(localeIso3Country ?? "")"
        timeZoneId = TimeZone.current.identifier

    }

    func toJson() -> [String: Any] {
        return [
            "deviceUuid": deviceUuid ?? "",
            "brand": brand ?? "",
            "model": model ?? "",
            "deviceName": deviceName ?? "",
            "sdkVersion": sdkVersion ?? "",
            "release": release ?? "",
            "phoneType": phoneType ?? "",
            "coresCpu": coresCpu ?? "",
            "physicalSize": physicalSize ?? "",
            "extSn": extSn ?? "",
            "deviceHeight": deviceHeight ?? "",
            "deviceWidth": deviceWidth ?? "",
            "dbmClass": dbmClass ?? "",
            "totalMemory": totalMemory ?? "",
            "video": video ?? "",
            "memory": memory ?? "",
            "storage": storage ?? "",
            "picCount": picCount ?? "",
            "idfaPermissions": idfaPermissions ?? "",
            "notificationPermissions": notificationPermissions ?? "",
            "calendarPermissions": calendarPermissions ?? "",
            "reminderPermissions": reminderPermissions ?? "",
            "phoneWifiSignalStrength": phoneWifiSignalStrength ?? "",
            "networkType": networkType ?? "",
            "ip": ip ?? "",
            "audioExternal": audioExternal ?? "",
            "audioInternal": audioInternal ?? "",
            "videoInternal": videoInternal ?? "",
            "videoExternal": videoExternal ?? "",
            "downloadFiles": downloadFiles ?? "",
            "isRootJailbreak": isRootJailbreak ?? "",
            "canCallPhone": canCallPhone ?? "",
            "keyboardType": keyboardType ?? "",
            "isUsingProxyPort": isUsingProxyPort ?? "",
            "isUsingVpn": isUsingVpn ?? "",
            "isUsbDebug": isUsbDebug ?? "",
            "lastBootTime": lastBootTime ?? "",
            "isMockLocation": isMockLocation ?? "",
            "isSimulator": isSimulator ?? "",
            "batteryPct": batteryPct ?? "",
            "isCharging": isCharging ?? "",
            "localeIso3Language": localeIso3Language ?? "",
            "localeDisplayLanguage": localeDisplayLanguage ?? "",
            "localeIso3Country": localeIso3Country ?? "",
            "language": language ?? "",
            "timeZoneId": timeZoneId ?? "",
        ]
    }
}

class LoanIosDeviceIosInfo {
    //应用的短版本字符串，例如 "1"
    var shortVersionString: String?
    //应用的完整版本号，例如 "1.1.3"
    var version: String?
    //应用的开发区域，例如 "en" 代表英语区域
    var developmentRegion: String?
    //当前服务的无线电接入技术，例如 "CTRadioAccessTechnologyWCDMA"
    var serviceCurrentRadioAccessTechnology: String?
    //是否允许 VoIP 功能
    var allowsVoip: Int?
    //移动国家代码 (MCC)，通常由数字组成，例如 "65535 65535"
    var mobileCountryCode: String?
    //移动网络代码 (MNC)，通常由数字组成，例如 "65535 65535"
    var mobileNetworkCode: String?
    //供应商标识符 (IDFV)，用于唯一标识设备供应商
    var idfv: String?

    func getData() {
        if let appVersion = Bundle.main.infoDictionary?["CFBundleShortVersionString"] as? String,
           let appBuild = Bundle.main.infoDictionary?["CFBundleVersion"] as? String {
            shortVersionString = appBuild
            version = appVersion
        }
        developmentRegion = "en"
        serviceCurrentRadioAccessTechnology = ModelTools.getRadioAccessTechnology()
        allowsVoip = ModelTools.isVoIPEnabled() ? 1 : 0
        mobileCountryCode = ModelTools.getMobileCountryCodeAndNetworkCode()["MCC"] as? String ?? ""
        mobileNetworkCode = ModelTools.getMobileCountryCodeAndNetworkCode()["MNC"] as? String ?? ""
        idfv = UIDevice.current.identifierForVendor?.uuidString
    }
    
    func toJson() -> [String: Any] {
        return [
            "shortVersionString": shortVersionString ?? "",
            "version": version ?? "",
            "developmentRegion": developmentRegion ?? "",
            "serviceCurrentRadioAccessTechnology": serviceCurrentRadioAccessTechnology ?? "",
            "allowsVoip": allowsVoip ?? "",
            "mobileCountryCode": mobileCountryCode ?? "",
            "mobileNetworkCode": mobileNetworkCode ?? "",
            "idfv": idfv ?? "",
        ]
    }
}

class LoanIosDeviceScreen {
    //显示宽度（以像素为单位）
    var widthPixels: CGFloat?
    //显示高度（以像素为单位）
    var heightPixels: CGFloat?
    //X 方向的像素密度，通常以 dpi 为单位
    var xdpi: String?
    //Y 方向的像素密度，通常以 dpi 为单位
    var ydpi: String?
    //屏幕密度（以 dpi 为单位）
    var densityDpi: Int?
    //屏幕密度，通常以字符串表示
    var density: String?
    //缩放密度，通常以字符串表示
    var scaledDensity: String?
    //分辨率，例如 "896X414"
    var resolution: String?
    //物理尺寸，通常以某个单位表示（例如，英寸），值为 0 表示未知或未测量
    var physicalSize: CGFloat?

    func getData() {
        widthPixels = ModelTools.getScreenWidthInPixels(UIScreen.main.bounds.size.width)
        heightPixels = ModelTools.getScreenWidthInPixels(UIScreen.main.bounds.size.height)
        xdpi = "\(ModelTools.calculateDPI(UIScreen.main.bounds.size.width) ?? 0)"
        ydpi = "\(ModelTools.calculateDPI(UIScreen.main.bounds.size.height) ?? 0)"
        let diagonalInPixels = sqrt(pow(UIScreen.main.bounds.size.width, 2) + pow(UIScreen.main.bounds.size.height, 2))
        densityDpi = Int(ModelTools.calculateDPI(diagonalInPixels) ?? 0)
        density = "\(densityDpi ?? 0)"
        scaledDensity = UIScreen.main.scale.description
        resolution = ModelTools.getScreenResolution()
        physicalSize = ModelTools.getDeviceDiagonalSizeInInches()
    }

    func toJson() -> [String: Any] {
        return [
            "widthPixels": widthPixels ?? "",
            "heightPixels": heightPixels ?? "",
            "xdpi": xdpi ?? "",
            "ydpi": ydpi ?? "",
            "densityDpi": densityDpi ?? "",
            "density": density ?? "",
            "scaledDensity": scaledDensity ?? "",
            "resolution": resolution ?? "",
            "physicalSize": physicalSize ?? "",
        ]
    }
}

class LoanIosDeviceStorage {
    //设备总内存大小（以字节为单位）
    var ramTotalSize: Int?
    //可用内存大小（以字节为单位）
    var ramUsableSize: Int?
    //可用的内部存储大小（以字节为单位）
    var internalStorageUsable: Int?
    //内部存储总大小（以字节为单位）
    var internalStorageTotal: Int?
    //应用程序总内存大小（以字节为单位）
    var appTotalMemory: Int?
    //应用程序最大内存限制（以字节为单位）
    var appMaxMemory: Int?
    //应用程序可用内存大小（以字节为单位）
    var appFreeMemory: Int?
    //可清理的 RAM 大小（以字节为单位）
    var ramCleanAbleSize: Int?
    //未激活的 RAM 大小（以字节为单位）
    var ramNotActiveSize: Int?
    //活跃的 RAM 大小（以字节为单位）
    var ramActiveSize: Int?
    //保持的 RAM 大小（以字节为单位）
    var ramKeepSize: Int?
    //已使用的 RAM 大小（以字节为单位）
    var ramUsedSize: Int?

    func getData() {
        ramTotalSize = ModelTools.getTotalMemoryInBytes()
        ramUsedSize = ModelTools.getAvailableMemoryInBytes()
        internalStorageUsable = ModelTools.getAvailableDiskSpaceInBytes()
        internalStorageTotal = ModelTools.getTotalDiskSpaceInBytes()
        appTotalMemory = ModelTools.getTotalDiskSpaceInBytes()
        appMaxMemory = ModelTools.getCurrentAppMemoryLimit()
        appFreeMemory = ModelTools.getAvailableMemoryForCurrentApp()
        ramCleanAbleSize = ModelTools.getCleanableRAMSize()
        ramNotActiveSize = ModelTools.getInactiveRAMSize()
        ramActiveSize = ModelTools.getActiveRAMSize()
        ramKeepSize = ModelTools.getWiredRAMSize()
        ramUsedSize = ModelTools.getUsedRAMSize()
    }

    func toJson() -> [String: Any] {
        return [
            "ramTotalSize": ramTotalSize ?? "",
            "ramUsableSize": ramUsableSize ?? "",
            "internalStorageUsable": internalStorageUsable ?? "",
            "internalStorageTotal": internalStorageTotal ?? "",
            "appTotalMemory": appTotalMemory ?? "",
            "appMaxMemory": appMaxMemory ?? "",
            "appFreeMemory": appFreeMemory ?? "",
            "ramCleanAbleSize": ramCleanAbleSize ?? "",
            "ramNotActiveSize": ramNotActiveSize ?? "",
            "ramActiveSize": ramActiveSize ?? "",
            "ramKeepSize": ramKeepSize ?? "",
            "ramUsedSize": ramUsedSize ?? "",
        ]
    }
}

class LoanIosDeviceProcess {
    //进程名称
    var processName: String?
    //活跃处理器数量
    var activeProcessorCount: Int?
    //处理器总数量
    var processorCount: Int?
    //物理内存（以字节为单位）
    var physicalMemory: Int?
    //进程标识符
    var processIdentifier: Int?
    //主机名
    var hostName: String?
    //环境信息
    var environment: String?
    //启动参数
    var arguments: String?
    //全局唯一标识符
    var globallyUniqueString: String?
    //操作系统版本字符串
    var operatingSystemVersionString: String?
    //系统运行时间（以秒为单位）
    var systemUptime: Int?
    //热状态
    var thermalState: Int?
    //是否启用低功耗模式
    var lowPowerModeEnabled: Int?

    func getData() {
        processName = ModelTools.getCurrentAppProcessName()
        activeProcessorCount = ModelTools.getActiveProcessorCount()
        processorCount = ModelTools.getTotalProcessorCount()
        physicalMemory = ModelTools.getPhysicalMemory()
        processIdentifier = ModelTools.getCurrentAppProcessIdentifier()
//        hostName = UIDevice.current.name
        environment = ProcessInfo.processInfo.environment.description
        arguments = CommandLine.arguments.joined(separator: ",")
        globallyUniqueString = UniqueIdentifierManager.getUniqueIdentifier()
        operatingSystemVersionString = UIDevice.current.systemVersion
        systemUptime = Int(ProcessInfo.processInfo.systemUptime)
        thermalState = ProcessInfo.processInfo.thermalState.rawValue
        lowPowerModeEnabled = ProcessInfo.processInfo.isLowPowerModeEnabled ? 1 : 0
    }

    func toJson() -> [String: Any] {
        return [
            "processName": processName ?? "",
            "activeProcessorCount": activeProcessorCount ?? "",
            "processorCount": processorCount ?? "",
            "physicalMemory": physicalMemory ?? "",
            "processIdentifier": processIdentifier ?? "",
            "hostName": hostName ?? "",
            "environment": environment ?? "",
            "arguments": arguments ?? "",
            "globallyUniqueString": globallyUniqueString ?? "",
            "operatingSystemVersionString": operatingSystemVersionString ?? "",
            "systemUptime": systemUptime ?? "",
            "thermalState": thermalState ?? "",
            "lowPowerModeEnabled": lowPowerModeEnabled ?? "",
        ]
    }
}

struct ModelTools {
    
    static func getRadioAccessTechnology() -> String {
        let networkInfo = CTTelephonyNetworkInfo()
        // 获取当前的无线电接入技术
        if let radioAccessTechnology = networkInfo.currentRadioAccessTechnology {
            switch radioAccessTechnology {
            case CTRadioAccessTechnologyGPRS:
                return "CTRadioAccessTechnologyGPRS"
            case CTRadioAccessTechnologyEdge:
                return "CTRadioAccessTechnologyEdge"
            case CTRadioAccessTechnologyWCDMA:
                return "CTRadioAccessTechnologyWCDMA"
            case CTRadioAccessTechnologyHSDPA:
                return "CTRadioAccessTechnologyHSDPA"
            case CTRadioAccessTechnologyHSUPA:
                return "CTRadioAccessTechnologyHSUPA"
            case CTRadioAccessTechnologyCDMA1x:
                return "CTRadioAccessTechnologyCDMA1x"
            case CTRadioAccessTechnologyCDMAEVDORev0:
                return "CTRadioAccessTechnologyCDMAEVDORev0"
            case CTRadioAccessTechnologyCDMAEVDORevA:
                return "CTRadioAccessTechnologyCDMAEVDORevA"
            case CTRadioAccessTechnologyCDMAEVDORevB:
                return "CTRadioAccessTechnologyCDMAEVDORevB"
            case CTRadioAccessTechnologyLTE:
                return "CTRadioAccessTechnologyLTE"
            default:
                if #available(iOS 14.1, *) {
                    if radioAccessTechnology == CTRadioAccessTechnologyNRNSA  {
                        return "CTRadioAccessTechnologyNRNSA"
                    }else if radioAccessTechnology == CTRadioAccessTechnologyNR {
                        return "CTRadioAccessTechnologyNR"
                    }
                } else {
                    return "Unknown"
                }
            }
        }
        return "Unknown"
    }
    
    static func isVoIPEnabled() -> Bool {
        if let backgroundModes = Bundle.main.infoDictionary?["UIBackgroundModes"] as? [String] {
            return backgroundModes.contains("voip")
        }
        return false
    }
    
    static func getMobileCountryCodeAndNetworkCode() -> [String: Any] {
        let networkInfo = CTTelephonyNetworkInfo()
        if let carrier = networkInfo.serviceSubscriberCellularProviders?.values.first {
            if let mobileCountryCode = carrier.mobileCountryCode, let mobileNetworkCode = carrier.mobileNetworkCode {
                return ["MCC": mobileCountryCode, "MNC": mobileNetworkCode]
            }
        }
        return [:]
    }
    
    static func getScreenWidthInPixels(_ value: CGFloat) -> CGFloat {
        let screenScale = UIScreen.main.scale
        let screenWidthInPixels = value * screenScale
        return screenWidthInPixels
    }
    
    static func calculateDPI(_ value: CGFloat) -> CGFloat? {
        let screenScale = UIScreen.main.scale
        let screenInPixels = value * screenScale
        let diagonalInInches: CGFloat = ModelTools.getDeviceDiagonalSizeInInches()
        let dpi = screenInPixels / diagonalInInches
        
        return dpi
    }
    
    static func getDeviceDiagonalSizeInInches() -> CGFloat {
        let deviceSizes: [String: CGFloat] = [
            "iPhone SE": 4.0,
            "iPhone 8": 4.7,
            "iPhone 8 Plus": 5.5,
            "iPhone X": 5.8,
            "iPhone XR": 6.1,
            "iPhone XS": 5.8,
            "iPhone XS Max": 6.5,
            "iPhone 11": 6.1,
            "iPhone 11 Pro": 5.8,
            "iPhone 11 Pro Max": 6.5,
            "iPhone 12": 6.1,
            "iPhone 12 Mini": 5.4,
            "iPhone 12 Pro": 6.1,
            "iPhone 12 Pro Max": 6.7,
            "iPad Pro (11-inch)": 11.0,
            "iPad Pro (12.9-inch)": 12.9
        ]
        let deviceModel = UIDevice.current.model
        if let size = deviceSizes[deviceModel] {
            return size
        }
        return 5.8
    }
    
    static func getScreenResolution() -> String {
        let screenSize = UIScreen.main.bounds.size
        let screenScale = UIScreen.main.scale
        let widthInPixels = Int(screenSize.width * screenScale)
        let heightInPixels = Int(screenSize.height * screenScale)
        return "\(widthInPixels)X\(heightInPixels)"
    }
    
    static func getTotalMemoryInBytes() -> Int {
        var size: Int = 0
        var sizeLength: Int = MemoryLayout<Int>.size
        let result = sysctlbyname("hw.memsize", &size, &sizeLength, nil, 0)
        if result == 0 {
            return size
        } else {
            return 0
        }
    }
    
    static func getAvailableMemoryInBytes() -> Int {
        var taskInfo = mach_task_basic_info()
        var count = mach_msg_type_number_t(MemoryLayout<mach_task_basic_info>.size) / 4
        let kerr: kern_return_t = withUnsafeMutablePointer(to: &taskInfo) {
            $0.withMemoryRebound(to: integer_t.self, capacity: 1) {
                task_info(mach_task_self_, task_flavor_t(MACH_TASK_BASIC_INFO), $0, &count)
            }
        }
        if kerr == KERN_SUCCESS {
            return Int(taskInfo.resident_size)
        } else {
            return 0
        }
    }
    
    static func getAvailableDiskSpaceInBytes() -> Int? {
        do {
            let attributes = try FileManager.default.attributesOfFileSystem(forPath: NSHomeDirectory())
            if let freeSize = attributes[.systemFreeSize] as? NSNumber {
                return freeSize.intValue
            }
        } catch {
            return 0
        }
        return 0
    }
    
    static func getTotalDiskSpaceInBytes() -> Int {
        do {
            let attributes = try FileManager.default.attributesOfFileSystem(forPath: NSHomeDirectory())
            if let totalSize = attributes[.systemSize] as? NSNumber {
                return totalSize.intValue
            }
        } catch {
            return 0
        }
        return 0
    }
    
    static func getCurrentAppMemoryUsage() -> Int {
        var info = task_vm_info()
        var count = mach_msg_type_number_t(MemoryLayout.size(ofValue: info) / MemoryLayout<integer_t>.size)
        let result = withUnsafeMutablePointer(to: &info) { pointer in
            pointer.withMemoryRebound(to: integer_t.self, capacity: Int(count)) { reboundPointer in
                task_info(mach_task_self_, task_flavor_t(TASK_VM_INFO), reboundPointer, &count)
            }
        }
        if result == KERN_SUCCESS {
            return Int(info.phys_footprint)
        } else {
            return 0
        }
    }
    
    static func getCurrentAppMemoryLimit() -> Int {
        var info = task_vm_info()
        var count = mach_msg_type_number_t(MemoryLayout.size(ofValue: info) / MemoryLayout<integer_t>.size)
        let result = withUnsafeMutablePointer(to: &info) { pointer in
            pointer.withMemoryRebound(to: integer_t.self, capacity: Int(count)) { reboundPointer in
                task_info(mach_task_self_, task_flavor_t(TASK_VM_INFO), reboundPointer, &count)
            }
        }
        if result == KERN_SUCCESS {
            return Int(info.virtual_size)
        } else {
            return 0
        }
    }
    
    static func getAvailableMemoryForCurrentApp() -> Int {
        var info = vm_statistics()
        var count = mach_msg_type_number_t(MemoryLayout.size(ofValue: info) / MemoryLayout<integer_t>.size)
        let result = withUnsafeMutablePointer(to: &info) { pointer in
            pointer.withMemoryRebound(to: integer_t.self, capacity: Int(count)) { reboundPointer in
                task_info(mach_task_self_, task_flavor_t(TASK_VM_INFO), reboundPointer, &count)
            }
        }
        if result == KERN_SUCCESS {
            let freeMemory = UInt64(info.free_count) * UInt64(vm_kernel_page_size)
            let inactiveMemory = UInt64(info.inactive_count) * UInt64(vm_kernel_page_size)
            return Int(freeMemory + inactiveMemory)
        } else {
            return 0
        }
    }
    
    static func getCleanableRAMSize() -> Int {
        var info = vm_statistics64()
        var count = mach_msg_type_number_t(MemoryLayout.size(ofValue: info) / MemoryLayout<integer_t>.size)
        let result = withUnsafeMutablePointer(to: &info) { pointer in
            pointer.withMemoryRebound(to: integer_t.self, capacity: Int(count)) { reboundPointer in
                task_info(mach_task_self_, task_flavor_t(TASK_VM_INFO), reboundPointer, &count)
            }
        }
        if result == KERN_SUCCESS {
            let freeMemory = UInt64(info.free_count) * UInt64(vm_kernel_page_size)
            let inactiveMemory = UInt64(info.inactive_count) * UInt64(vm_kernel_page_size)
            return Int(freeMemory + inactiveMemory)
        } else {
            return 0
        }
    }
    
    static func getInactiveRAMSize() -> Int {
        var info = vm_statistics64()
        var count = mach_msg_type_number_t(MemoryLayout.size(ofValue: info) / MemoryLayout<integer_t>.size)
        let result = withUnsafeMutablePointer(to: &info) { pointer in
            pointer.withMemoryRebound(to: integer_t.self, capacity: Int(count)) { reboundPointer in
                task_info(mach_task_self_, task_flavor_t(TASK_VM_INFO), reboundPointer, &count)
            }
        }
        if result == KERN_SUCCESS {
            let inactiveMemory = UInt64(info.inactive_count) * UInt64(vm_kernel_page_size)
            return Int(inactiveMemory)
        } else {
            return 0
        }
    }
    
    static func getActiveRAMSize() -> Int {
        var info = vm_statistics64()
        var count = mach_msg_type_number_t(MemoryLayout.size(ofValue: info) / MemoryLayout<integer_t>.size)
        let result = withUnsafeMutablePointer(to: &info) { pointer in
            pointer.withMemoryRebound(to: integer_t.self, capacity: Int(count)) { reboundPointer in
                task_info(mach_task_self_, task_flavor_t(TASK_VM_INFO), reboundPointer, &count)
            }
        }
        if result == KERN_SUCCESS {
            let activeMemory = UInt64(info.active_count) * UInt64(vm_kernel_page_size)
            return Int(activeMemory)
        } else {
            return 0
        }
    }
    
    static func getWiredRAMSize() -> Int {
        var info = vm_statistics64()
        var count = mach_msg_type_number_t(MemoryLayout.size(ofValue: info) / MemoryLayout<integer_t>.size)
        let result = withUnsafeMutablePointer(to: &info) { pointer in
            pointer.withMemoryRebound(to: integer_t.self, capacity: Int(count)) { reboundPointer in
                task_info(mach_task_self_, task_flavor_t(TASK_VM_INFO), reboundPointer, &count)
            }
        }
        if result == KERN_SUCCESS {
            let wiredMemory = UInt64(info.wire_count) * UInt64(vm_kernel_page_size)
            return Int(wiredMemory)
        } else {
            return 0
        }
    }
    
    static func getUsedRAMSize() -> Int {
        var info = vm_statistics64()
        var count = mach_msg_type_number_t(MemoryLayout.size(ofValue: info) / MemoryLayout<integer_t>.size)
        let result = withUnsafeMutablePointer(to: &info) { pointer in
            pointer.withMemoryRebound(to: integer_t.self, capacity: Int(count)) { reboundPointer in
                task_info(mach_task_self_, task_flavor_t(TASK_VM_INFO), reboundPointer, &count)
            }
        }
        if result == KERN_SUCCESS {
            let activeMemory = UInt64(info.active_count) * UInt64(vm_kernel_page_size)
            let inactiveMemory = UInt64(info.inactive_count) * UInt64(vm_kernel_page_size)
            let wiredMemory = UInt64(info.wire_count) * UInt64(vm_kernel_page_size)
            let usedMemory = activeMemory + inactiveMemory + wiredMemory
            return Int(usedMemory)
        } else {
            return 0
        }
    }
    
    static func getCurrentAppProcessName() -> String? {
        let processInfo = ProcessInfo.processInfo
        return processInfo.processName
    }
    
    static func getActiveProcessorCount() -> Int {
        let processInfo = ProcessInfo.processInfo
        return processInfo.activeProcessorCount
    }
    
    static func getTotalProcessorCount() -> Int {
        let processInfo = ProcessInfo.processInfo
        return processInfo.processorCount
    }
    
    static func getPhysicalMemory() -> Int {
        var size: UInt64 = 0
        var sizeLength = MemoryLayout<UInt64>.size
        let result = sysctlbyname("hw.physmem", &size, &sizeLength, nil, 0)
        if result == 0 {
            return Int(size)
        } else {
            return 0
        }
    }
    
    static func getCurrentAppProcessIdentifier() -> Int {
        let processInfo = ProcessInfo.processInfo
        return Int(processInfo.processIdentifier)
    }
    
    static func getSDKVersion() -> String {
        let version = ProcessInfo.processInfo.operatingSystemVersion
        return "iOS \(version.majorVersion).\(version.minorVersion).\(version.patchVersion)"
    }
    
    static func getPhoneCapability() -> Int {
        let networkInfo = CTTelephonyNetworkInfo()
        if let carrier = networkInfo.serviceSubscriberCellularProviders?.first?.value, carrier.mobileNetworkCode != nil {
            return 1
        } else {
            return 0
        }
    }
    
    static func getVideoCount(completion: @escaping (Int) -> Void) {
        PHPhotoLibrary.requestAuthorization { status in
            if status == .authorized {
                let videoOptions = PHFetchOptions()
                videoOptions.predicate = NSPredicate(format: "mediaType == %d", PHAssetMediaType.video.rawValue)
                let videos = PHAsset.fetchAssets(with: videoOptions)
                completion(videos.count)
            } else {
                completion(0)
            }
        }
    }
    
    static func getPhotoCount(completion: @escaping (Int) -> Void) {
        PHPhotoLibrary.requestAuthorization { status in
            if status == .authorized {
                let videoOptions = PHFetchOptions()
                videoOptions.predicate = NSPredicate(format: "mediaType == %d", PHAssetMediaType.image.rawValue)
                let videos = PHAsset.fetchAssets(with: videoOptions)
                completion(videos.count)
            } else {
                completion(0)
            }
        }
    }
    
    static func getMemoryUsage() -> Int {
        var taskInfo = mach_task_basic_info()
        var count = mach_msg_type_number_t(MemoryLayout<mach_task_basic_info>.size) / 4
        let kerr: kern_return_t = withUnsafeMutablePointer(to: &taskInfo) {
            $0.withMemoryRebound(to: integer_t.self, capacity: 1) {
                task_info(mach_task_self_, task_flavor_t(MACH_TASK_BASIC_INFO), $0, &count)
            }
        }
        if kerr == KERN_SUCCESS {
            return Int(taskInfo.resident_size)
        } else {
            return 0
        }
    }
    
    static func getNetworkType(completion: @escaping (String) -> Void) {
        let monitor = NWPathMonitor()
        let queue = DispatchQueue(label: "Monitor")
        monitor.start(queue: queue)
        monitor.pathUpdateHandler = { path in
            if path.status == .satisfied {
                if path.usesInterfaceType(.wifi) {
                    completion("WiFi")
                } else if path.usesInterfaceType(.cellular) {
                    let networkInfo = CTTelephonyNetworkInfo()
                    if let carrier = networkInfo.serviceSubscriberCellularProviders?.first?.value {
                        let radioAccessTechnology = networkInfo.serviceCurrentRadioAccessTechnology?.first?.value
                        var networkType: String = "Unknow"
                        switch radioAccessTechnology {
                        case CTRadioAccessTechnologyGPRS:
                            networkType = "2G"
                        case CTRadioAccessTechnologyEdge:
                            networkType = "2.5G"
                        case CTRadioAccessTechnologyWCDMA:
                            networkType = "3G"
                        case CTRadioAccessTechnologyHSDPA:
                            networkType = "3G"
                        case CTRadioAccessTechnologyHSUPA:
                            networkType = "3G"
                        case CTRadioAccessTechnologyCDMA1x:
                            networkType = "2G"
                        case CTRadioAccessTechnologyCDMAEVDORev0:
                            networkType = "3G"
                        case CTRadioAccessTechnologyCDMAEVDORevA:
                            networkType = "3G"
                        case CTRadioAccessTechnologyCDMAEVDORevB:
                            networkType = "3G"
                        case CTRadioAccessTechnologyLTE:
                            networkType = "4G"
                        default:
                            if #available(iOS 14.1, *) {
                                if radioAccessTechnology == CTRadioAccessTechnologyNRNSA || radioAccessTechnology == CTRadioAccessTechnologyNR {
                                    networkType = "5G"
                                }
                            }
                        }
                        completion(networkType)
                    }
                }
            } else {
                completion("Unknow")
            }
        }
    }
    
    static func canMakePhoneCalls() -> Bool {
        let networkInfo = CTTelephonyNetworkInfo()
        if let carrier = networkInfo.serviceSubscriberCellularProviders?.first?.value {
            return carrier.mobileNetworkCode != nil
        }
        return false
    }
    
    static func checkVPNStatus(completion: @escaping (Bool) -> Void) {
        let vpnManager = NEVPNManager.shared()
        vpnManager.loadFromPreferences { error in
            if let error = error {
                completion(false)
                return
            }
            completion(vpnManager.connection.status == .connected)
        }
    }
    
    static func isRunningOnSimulator() -> Bool {
#if targetEnvironment(simulator)
        return true
#else
        return false
#endif
    }
    
    static func isDeviceCharging() -> Bool {
        let device = UIDevice.current
        device.isBatteryMonitoringEnabled = true
        let batteryState = device.batteryState
        return batteryState == .charging || batteryState == .full
    }
    
    static func getBatteryPercentage() -> CGFloat {
        let device = UIDevice.current
        device.isBatteryMonitoringEnabled = true
        let batteryLevel = device.batteryLevel
        if batteryLevel >= 0 {
            return CGFloat(batteryLevel * 100)
        }
        return -1
    }
    
    static func isDeviceJailbroken() -> Bool {
        // 检查常见的越狱文件
        let jailbrokenPaths = [
            "/Applications/Cydia.app",
            "/Library/MobileSubstrate/MobileSubstrate.dylib",
            "/bin/bash",
            "/usr/sbin/sshd",
            "/etc/apt"
        ]
        for path in jailbrokenPaths {
            if FileManager.default.fileExists(atPath: path) {
                return true
            }
        }
        // 检查可以写入的系统目录
        let testPath = "/private/" + UUID().uuidString
        do {
            try "Test".write(to: URL(fileURLWithPath: testPath), atomically: true, encoding: .utf8)
            try FileManager.default.removeItem(atPath: testPath)
            return false
        } catch {
            return true
        }
    }
    
    static func checkProxy() -> Bool {
        guard let proxy = CFNetworkCopySystemProxySettings()?.takeUnretainedValue() else { return false }
        guard let dict = proxy as? [String: Any] else { return false }
        let isUsed = dict.isEmpty
        guard let HTTPProxy = dict["HTTPProxy"] as? String else { return false }
        if(HTTPProxy.count>0){
            return true
        }
        return false
    }
    
    static func getAllAudioSize(completion: @escaping (Int) -> Void) {
        var totalSize: UInt64 = 0
        PHPhotoLibrary.requestAuthorization { status in
            guard status == .authorized else {
                completion(0)
                return
            }
            let fetchOptions = PHFetchOptions()
            fetchOptions.predicate = NSPredicate(format: "mediaType == %d", PHAssetMediaType.audio.rawValue)
            let audioAssets = PHAsset.fetchAssets(with: fetchOptions)
            let totalAssets = audioAssets.count
            var processedAssets = 0
            audioAssets.enumerateObjects { asset, _, _ in
                let resources = PHAssetResource.assetResources(for: asset)
                for resource in resources {
                    if let fileSize = resource.value(forKey: "fileSize") as? Int {
                        totalSize += UInt64(fileSize)
                    }
                }
                processedAssets += 1
                if processedAssets == totalAssets {
                    completion(Int(totalSize))
                }
            }
        }
    }
    
    static func getAllVideoSize(completion: @escaping (Int) -> Void) {
        var totalSize: UInt64 = 0
        PHPhotoLibrary.requestAuthorization { status in
            guard status == .authorized else {
                completion(0)
                return
            }
            let fetchOptions = PHFetchOptions()
            fetchOptions.predicate = NSPredicate(format: "mediaType == %d", PHAssetMediaType.video.rawValue)
            let videoAssets = PHAsset.fetchAssets(with: fetchOptions)
            let totalAssets = videoAssets.count
            var processedAssets = 0
            videoAssets.enumerateObjects { asset, _, _ in
                let resources = PHAssetResource.assetResources(for: asset)
                for resource in resources {
                    if let fileSize = resource.value(forKey: "fileSize") as? Int {
                        totalSize += UInt64(fileSize)
                    }
                }
                processedAssets += 1
                if processedAssets == totalAssets {
                    completion(Int(totalSize))
                }
            }
        }
    }
    
}

class UniqueIdentifierManager {
    static let keychain = Keychain(service: Bundle.main.bundleIdentifier!)
    static let uniqueIdentifierKey = "uniqueIdentifierKey"
 
    class func getUniqueIdentifier() -> String? {
        let uniqueIdentifier = keychain[uniqueIdentifierKey]
        if uniqueIdentifier == nil {
            let generatedIdentifier: String = UUID().uuidString
            keychain[uniqueIdentifierKey] = generatedIdentifier
            return generatedIdentifier
        }
        return uniqueIdentifier
    }
}

